using Mono.Boost.Graph;
using System.Collections.Generic;
using NUnit.Framework;
using System;

[TestFixture]
public class TestFlows
{
    public uint inflow<GT,FT> (GT g,FT flow,uint v)
        where GT:IGraph
        where FT:IDictionary<uint,uint>
    {
        uint res = 0;
        foreach(EdgeInfo ei in g.incoming(v))
            res += flow[ei.id];

        return res;
    }
    public uint outflow<GT,FT> (GT g,FT flow,uint v)
        where GT:IGraph
        where FT:IDictionary<uint,uint>
    {
        uint res = 0;
        foreach(EdgeInfo ei in g.outgoing(v))
            res += flow[ei.id];

        return res;
    }
    public void run_edmonds_karp(uint verticesCount, Pair<uint,uint>[] edges, StaticPropertyMap<uint> maxFlow, uint good)
    {
        StaticGraph g = new StaticGraph(verticesCount, edges);
        StaticPropertyMap<uint> flow = new StaticPropertyMap<uint>(g.highestEdgeId+1);
        uint mflow = Flows.edmonds_karp(g,flow,maxFlow,0,1);

        Assert.AreEqual(good, mflow, "Wrong calculated flow");
        foreach(uint v in g.vertices)
        {
            uint iflow = inflow(g,flow,v);
            uint oflow = outflow(g,flow,v);
            if(v == 0)
                Assert.AreEqual(good, oflow - iflow, "Bad flow from source");
            else if(v == 1)
                Assert.AreEqual(good, iflow - oflow, "Bad flow into destination");
            else
                Assert.AreEqual(iflow, oflow, "Kirchoff law broken");
        }
    }
    [Test]
    public void test()
    {
        Pair<uint,uint>[] tab = new Pair<uint,uint>[]{
            new Pair<uint,uint>(0,2),
            new Pair<uint,uint>(2,4),
            new Pair<uint,uint>(2,5),
            new Pair<uint,uint>(0,3),
            new Pair<uint,uint>(5,6),
            new Pair<uint,uint>(3,5),
            new Pair<uint,uint>(6,1),
            new Pair<uint,uint>(4,1),
            new Pair<uint,uint>(5,4),
        };
        StaticPropertyMap<uint> maxFlow = new StaticPropertyMap<uint>(9);
        maxFlow[0] = 12;
        maxFlow[1] = 2;
        maxFlow[2] = 7;
        maxFlow[3] = 6;
        maxFlow[4] = 8;
        maxFlow[5] = 5;
        maxFlow[6] = 20;
        maxFlow[7] = 8;
        maxFlow[8] = 7;
        run_edmonds_karp(7,tab,maxFlow,14);

        maxFlow[2] = 9;
        run_edmonds_karp(7,tab,maxFlow,16);


    }
}
